package timeutil

import (
	"math"
	"strconv"
	"time"
)

// 0:表示精确到秒, 3:表示存储毫秒, 6表示存储微秒
const RFC3339Z = "2006-01-02T15:04:05Z07:00"
const RFC3339E3Z = "2006-01-02T15:04:05.999Z07:00"
const RFC3339E6Z = "2006-01-02T15:04:05.999999Z07:00"
const RFC3339Milli = "2006-01-02T15:04:05.999Z"
const RFC3339Micro = "2006-01-02T15:04:05.999999Z"
const DateYmdHis = "2006-01-02 15:04:05"
const DateYmd = "2006-01-02"
const DateTimeLayoutTZ = "2006-01-02T15:04:05Z"

func GetTimeWithMS() float64 {
	return float64(time.Now().UnixNano()) / 1000000000
}

func GetMillisecond() int64 {
	return time.Now().UnixNano() / int64(time.Millisecond)
}

func GetMicrosecond() int64 {
	return GetMicrosecondByTime(time.Now())
}

func GetMicrosecondByTime(t time.Time) int64 {
	return t.UnixNano() / int64(time.Microsecond)
}

func GetTimeFromE6(timestampE6 int64) time.Time {
	return time.Unix(timestampE6/1e6, (timestampE6%1e6)*1e3)
}

func GetE6FromTime(t time.Time) int64 {
	return t.Unix()*1e6 + int64(t.Nanosecond())/1e3
}

func TimeAt() string {
	return time.Now().Format("2006-01-02 15:04:05.000000")
}

func TimeAtHis() string {
	return time.Now().Format(DateYmdHis)
}

func TimeZero() int64 {
	timeStr := time.Now().Format("2006-01-02")
	t, _ := time.Parse("2006-01-02", timeStr)
	timeNumber := t.Unix()
	return timeNumber
}

// ToString 转成字符串时间
func ToString(t time.Time) string {
	return t.Format("2006-01-02T15:04:05.000Z")
}

func ToStringYmd(t time.Time) string {
	if t.IsZero() {
		return ""
	}
	return t.Format("2006-01-02")
}

func ToTimeYmd(ds string) time.Time {
	if ds == "" {
		return time.Time{}
	}
	date, err := time.Parse("2006-01-02", ds)
	if err != nil {
		return time.Time{}
	}
	return date
}

func UnixMicroToTime(t uint64) time.Time {
	sec := t / 1e6
	nano := (t - sec*1e6) * 1e3
	return time.Unix(int64(sec), int64(nano)).UTC()
}

func MinTimeValue() time.Time {
	return time.Time{} // 临时对象的值默认是0, 对应时间: 0001-01-01 00:00:00 +0000 UTC
}

func MaxTimeValue() time.Time {
	// number of seconds between Year 1 and 1970 (62135596800 seconds)
	return time.Unix(math.MaxInt64-62135596800, 999999999) // 减去一个1970前的偏移, 不然t.Before()会有问题
}

func MinTimeE6() int64 {
	return 0 // 临时对象的值默认是0, 对应时间: 0001-01-01 00:00:00 +0000 UTC
}

func MaxTimeE6() int64 {
	// number of seconds between Year 1 and 1970 (62135596800 seconds)
	return math.MaxInt64 - 62135596800 // 减去一个1970前的偏移, 不然t.Before()会有问题
}

func NowMicro() time.Time {
	return time.Now().Round(time.Microsecond)
}

func NowNanoInt64() int64 {
	return time.Now().UnixNano()
}

// 格式化pb时间
func GetTimeFromE9(timestampE6 int64) time.Time {
	return time.Unix(timestampE6/1e9, (timestampE6%1e9)*1e3)
}

// 毫秒时间戳转化成UTC时间
func GetFmtFromUinxNano(timestamp int64) string {
	return time.Unix(timestamp/1e3, 0).Format("2006-01-02T15:04:05.000Z")
}

// 秒 转化成UTC时间
func GetFmtFromUinx(timestamp int64) string {
	return time.Unix(timestamp, 0).Format("2006-01-02 15:04:05.000000")
}

// 毫秒 string 转 秒时间戳
func GetFromStringToUnix(timestamp string) (int64, error) {
	t, err := time.Parse("2006-01-02 15:04:05.000000", timestamp)
	if err != nil {
		return 0, err
	}
	return t.Unix(), nil
}

// FloatMsStringToUnix 毫秒转为时间戳（eg: "1651747612.787" to 1651747612787）
func FloatMsStringToUnix(timestampMs string) (int64, error) {
	f, err := strconv.ParseFloat(timestampMs, 3)
	if err != nil {
		return 0, err
	}

	return int64(f * 1e3), nil
}

func IsBeforeFmtAdrTime(fmtAdrTime string) bool {
	now := time.Now()
	fat, err := time.Parse(DateYmdHis, fmtAdrTime)
	if err != nil {
		return false
	}

	return now.Before(fat)
}

// GetDateTZ2Unix 获取指定时间的unix时间戳
func GetDateTZ2Unix(date string) (int64, error) {
	t, err := time.ParseInLocation(DateTimeLayoutTZ, date, time.Local)
	if err != nil {
		return 0, err
	}
	return t.Unix(), nil
}
